package config

import (
	"flag"
	"log"
	"os"
	"strings"

	"github.com/golang/glog"
)

var c Configer

// Configer defines how to get and set value from configuration raw data.
type Configer interface {
	Set(key, val string) error
	String(key string) string
	Int(key string) (int, error)
	Int64(key string) (int64, error)
	Bool(key string) (bool, error)
	Float(key string) (float64, error)
}

func InitConfig(path string) error {
	var err error
	c, err = NewDefaultConfig(path)
	return err
}

func GetConfig() Configer {
	return c
}

func init() {
	Init()
	flag.Parse()
	defer glog.Flush()
	log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)

	conf := os.Getenv("ConfPath")
	if len(conf) == 0 {
		conf = "./conf/app.conf"
	}
	glog.Infof("conf path: %v", conf)

	err := InitConfig(conf)
	if err != nil {
		glog.Fatalf("init config failed, %v", err)
	}

	setValues()
}

var (
	KubernetesAddress = "kubernetesAddress"
)

var (
	masterURL    string
	MasterURLKey string = "masterURL"

	kubeconfig    string
	KubeConfigKey string = "kubeconfig"

	leaderElectionLockName    string
	LeaderElectionLockNameKey string = "leaderElectionLockName"

	namespace    string
	NamespaceKey string = "namespace"

	leaderElectionEnable    string
	LeaderElectionEnableKey string = "LeaderElectionEnable"
)

func setValues() {
	if masterURL != "" {
		_ = c.Set(MasterURLKey, masterURL)
	}

	if kubeconfig != "" {
		_ = c.Set(KubeConfigKey, kubeconfig)
	}

	if leaderElectionLockName != "" {
		_ = c.Set(LeaderElectionLockNameKey, leaderElectionLockName)
	}

	if namespace != "" {
		_ = c.Set(NamespaceKey, namespace)
	}

	if leaderElectionEnable != "" {
		_ = c.Set(LeaderElectionEnableKey, leaderElectionEnable)
	}

	// set all env into config
	environ := os.Environ()
	for _, v := range environ {
		strs := strings.Split(v, "=")
		if len(strs) != 2 {
			continue
		}
		_ = c.Set(strs[0], strs[1])
	}
}

func Init() {
	flag.StringVar(&masterURL, "masterURL", "", "kubernetes master url")
	flag.StringVar(&kubeconfig, "kubeconfig", "", "kubeconfig file path")
	flag.StringVar(&leaderElectionLockName, "leader-election-lock-name", "", "leader election lock name in kubernetes")
	flag.StringVar(&namespace, "namespace", "", "namespace for election leader")
	flag.StringVar(&leaderElectionEnable, "leader-election-enable", "", "enable leader election")
}
